home *** CD-ROM | disk | FTP | other *** search
/ .net (French) 1996 November / .net Magazine (FR) - Issue 01 - Nov 1996.iso / mac / Butineur / Netscape Plug-ins / KM's QuickTime plug / Sources / MoviePlug9.p < prev    next >
Text File  |  1996-02-05  |  29KB  |  847 lines

  1. {My movie plugin made from Netscape's shell file from the New SDK 0.7.
  2. Interface bugs are probably mine, not Netscape's.
  3.  
  4. This project has some trouble with Netscape's windows either by my bugs or Netscape's.
  5. Expect to see winow updating flaws.
  6. Kevin McMurtrie  mcmurtri@wco.com
  7. 2/5/95, AKA 0.2.0}
  8.  
  9.  
  10. {$D-}
  11. unit ViewPict;
  12. interface
  13. uses npapi;
  14.  
  15.  
  16. function NPP_Initialize:NPError;
  17. procedure NPP_Shutdown;
  18. function NPN_MemAlloc (size: longint):Ptr; C; EXTERNAL;
  19. procedure NPN_MemFree (buf: Ptr); C; EXTERNAL;
  20. function NPP_New (pluginType:NPMIMEType;
  21.                 var instance:NPP;
  22.                 mode: integer;
  23.                 argc: integer;
  24.                 argn: arglist;
  25.                 argv: arglist;
  26.                 recalled: NPSavedDataPtr):NPError;
  27. function NPP_Destroy (var instance:NPP; var save: NPSavedDataPtr):NPError;
  28. function NPP_SetWindow (var instance: NPP; NwindowP: NPWindowPtr): NPError;
  29. function NPP_NewStream        (var instance: NPP;
  30.                             Mtype: NPMIMEType;
  31.                             var stream: NPStream;
  32.                             seekable: boolean;
  33.                             var stype: integer):NPError;
  34. function NPP_WriteReady (var instance: NPP; var stream: NPStream):longint;
  35. function NPP_Write (var instance: NPP; var stream: NPStream; offset, len: longint; buffer: Ptr):longint;
  36. function NPP_DestroyStream (var instance: NPP; var stream: NPStream; reason: NPError):NPError;
  37. procedure NPP_StreamAsFile (var instance: NPP; var stream: NPStream; fname: charstar);
  38. procedure NPP_Print (var instance: NPP; var printInfo: NPPrint);
  39. function NPP_HandleEvent (var instance: NPP; var event: EventRecord):integer;
  40.  
  41.  
  42.  
  43. implementation
  44. uses npapi, Windows, Speech,Movies, Fonts, TextUtils, ImageCompression, GestaltEqu, Resources;
  45.  
  46. var
  47.     {$J+}
  48.     gResFile: integer;EXTERNAL;        {Global variable in pascal_npmac.cpp that is my resource ref ID#}
  49.     {$J-}
  50. Type
  51.  
  52.     SavedDataT = record                {This is information that is saved at Destroy and recalled at New}
  53.         LastTime:TimeValue;
  54.         LastRate:Fixed;
  55.         LastVol: integer;                {16 bit fixed}
  56.     end;
  57.     SavedDataPtrT = ^SavedDataT;    {This is a pointer-type to the data used for storage across Destroy and New}
  58.  
  59.  
  60. OptionsT = record            {Options used when opening/displaying the movie}
  61.     CX, CY : boolean;            {Auto center h and v placement}
  62.     F: boolean;                    {Force fit to rect}
  63.     AL, AT: boolean;            {If not CX/CY or F then manual align Left/Right and Top/Bottom}
  64.     CS: (Auto, Visible, Hidden, None, Badge);    {Controller usage}
  65.     
  66.     PlayRate: Fixed;            {Initial play rate (32bit fixed) }
  67.     
  68.     LP: (Once, Linear, Palidrome);    {No loop, loop linear, loop palidrome}
  69.     
  70.     Vol: integer;                {Movie volume (16 bit fixed) }
  71.     MediaKind: char;            {What kind of a movie this is.  From my resource.  (A-audio, V-video, S-still) }
  72.     
  73.     Slide: boolean;                {Slideshow mode - play all frames, no sound}
  74.     HighQ:boolean;                {High quality (slow!!) }
  75.     UsePalette:boolean;            {Use movie's custom palette for whole window}
  76.     
  77.     StartPosition: TimeValue;    {This is used for recalling the last position before Destroy, may later HTML option too} 
  78. end;
  79.  
  80.  
  81. GraphicsStateT = record        {Saved drawing states.  Set by SetupDrawState for RestoreDrawState.}
  82.     SPort: GrafPtr;                {The port that was previously in use}
  83.     SOrigin: Point;                {To watch for any motion of window contents.  Set by SetupDrawState for SetupDrawState.}
  84.     SWMOrigin: Point;            {Window Manager's previous origin.  Set by SetupDrawState for RestoreDrawState.}            
  85.     DidSave:boolean;            {The info here is valid.  Set by SetupDrawState for RestoreDrawState.}
  86.     PortChanged: boolean;        {The grafport changed.  Set by the procedure changing the port for SetupDrawState.}
  87. end;
  88.  
  89. MyDataT = record            {This is all the data associated with a plug-in instance}
  90.     NWindP: NPWindowPtr;            {Netscape window}
  91.     check1: ^NP_Port;                {check1 and check2 are for testing the validity of Netscape's window data╔ }
  92.     check2: CGrafPtr;                { ╔a bug causes corrupt data during update events}
  93.     
  94.     Loaded: boolean;                {Are we done loading?}
  95.     
  96.     TheFile: FSSpec;                {Location of file on disk}
  97.     MacFileType:OSType;                {Type of file - MooV, WAVE, etc.  Set when stream is created}
  98.     MovFileRef: integer;            {Movie's reference to the file}
  99.     
  100.     Mov: Movie;                        {The movie}
  101.     MovContr: ComponentInstance;    {The controller}
  102.     
  103.     
  104.     TempRegion: RgnHandle;            {Premade RgnHandle - Used for masking or whatever needs a quick RgnHandle for temporary calculations.}
  105.     GraphicsState: GraphicsStateT;    {Window and graphics saved states}
  106.     Options: OptionsT;                {HTML options}
  107.     end;
  108.     
  109. MyDataP = ^MyDataT;
  110.  
  111.  
  112. function Corruption (var dat: MyDataT): boolean;    {Has Netscape magicly changed the window param storage to garbage?}
  113. begin
  114.     with dat do if (NWindP<>nil) then Corruption:= (check1 <> NWindP^.window) | (check2 <> NWindP^.window^.port)
  115.                     else Corruption:=false;
  116. end;
  117.     
  118. procedure WhatIsIt (var MimeKind:Str255; var MacType:OSType; var MediaKind:char);    {What should the Mac file type be}
  119. var                                                                                    {And what kind of media is it? }
  120.     i:integer;
  121.     s:Str255;    {Temp string}
  122.     r:integer;    {Temp resource file ID}
  123.     err:OSErr;
  124. begin
  125.     r:=CurResFile;
  126.     err:=ResError;
  127.     UseResFile (gResFile);
  128.     err:=ResError;
  129.     
  130.     i:=0;
  131.     repeat                                        {Find index of this MIME type in my acceptance list - OK to go to end}
  132.         i:=succ(i);
  133.         GetIndString (s, 128, i*2 -1);
  134.     until (length(s)=0) or (s=MimeKind);
  135.     
  136.     GetIndString (s, 129, i*2);                    {Get the file kind (Video Still Audio) from my matching type list}
  137.  
  138.     
  139.     MediaKind:=s[1];
  140.     
  141.     GetIndString (s, 129, i*2 -1);                {Get the Mac file type from my matching type list}
  142.  
  143.     MacType[1]:= s[1];                            {Return the file type}
  144.     MacType[2]:= s[2];
  145.     MacType[3]:= s[3];
  146.     MacType[4]:= s[4];
  147.     
  148.     UseResFile (r);
  149. end;
  150.  
  151.  
  152. function OpenFromFile (var dat: MyDataT): OSErr;    {Open the movie file specified in Mov.TheFile}
  153. var                                                    {Translate the file if it isn't a QuickTime movie}
  154.     err, Xerr:OSErr;  {err - saved error, Xerr - unsaved error}
  155.     res: integer;
  156.     changed: boolean;
  157.     info:FInfo;
  158. begin
  159.     with dat do begin
  160.         Xerr:= OpenMovieFile(TheFile, MovFileRef, fsCurPerm);    {Open the file}
  161.         res:=0;
  162.         Mov:=nil;
  163.         err:= NewMovieFromFile(Mov, MovFileRef, res, nil, newMovieActive + newMovieDontResolveDataRefs, changed);    {Try opening it}
  164.         
  165.         if Mov = nil then                            {Didn't work, must do a QT import}
  166.         begin
  167.             Xerr:= CloseMovieFile (MovFileRef);        {Close & start over}
  168.             
  169.             Xerr:= FSpGetFInfo (TheFile, info);        {Set the cache file to the correct Mac file type}
  170.             info.fdType:= MacFileType;
  171.             info.fdFlags:= BAnd(BNot (kHasBeenInited),info.fdFlags);
  172.             err:= FSpSetFInfo (TheFile, info);
  173.             if err = noErr then
  174.             begin
  175.                 err:=ConvertFileToMovieFile (TheFile, TheFile, info.fdCreator, smCurrentScript, res, 0, nil, nil, 0);    {Convert}
  176.                 if err = noErr then
  177.                 begin
  178.                     Xerr := OpenMovieFile(TheFile, MovFileRef, fsCurPerm);    {Retry opening}
  179.                     res:=0;
  180.                     err:= NewMovieFromFile(Mov, MovFileRef, res, nil, newMovieActive + newMovieDontResolveDataRefs, changed);
  181.                     if Mov <> nil then
  182.                     begin
  183.                         err:= UpdateMovieResource (Mov, MovFileRef, res, 'Movie data conversion');    {Save changes to avoid reconvering later}
  184.                     end;
  185.                 end;
  186.             end;
  187.         end;  {Must do a QT import}
  188.         
  189.         Xerr:= CloseMovieFile (MovFileRef);        {OK to close it - no editing will be done}
  190.     end;
  191.     OpenFromFile:=err;
  192. end;
  193.  
  194.  
  195.  
  196. procedure SetTheMovieSize (var dat: MyDataT);    {Set the movie size based on the window info and HTML options}
  197. const
  198.     ContHeight = 16;    {Assumed size of movie controller}
  199.     MinSize = 9;        {Movies < 3 pixels squared, such as sound tracks, will be resized to a controller}
  200. var
  201.     m:MatrixRecord;
  202.     CompErr: ComponentResult;
  203.     MovBox, ContBox: Rect;
  204.     ContVis:boolean;
  205.     
  206. begin
  207.     with MovBox, dat, dat.NWindP^, dat.Options do begin
  208.         SetIdentityMatrix (m);                    {Take off any saved scaling}
  209.         SetMovieMatrix (Mov, m);
  210.         GetMovieBox(Mov, MovBox);
  211.         
  212.         OffsetRect(MovBox, -left, -top);
  213.         
  214.         if F or ((width*height) < MinSize) then        {Forced size or near zero destination}
  215.         begin
  216.             ContVis:= CS=Visible;        {Controller only if manually set}
  217.             right:=width; bottom:= (height - ord(ContVis)*ContHeight);    {Make room for controller, if needed}
  218.         end else
  219.         begin        {Auto size}
  220.         
  221.             if (longint(right)*longint(bottom)) < MinSize then    {Invalid dimensions - too small.  Make full controller if OK}
  222.             begin
  223.                 right:=width;
  224.                 ContVis:= (CS=Auto) or (CS=Visible);        {Visible controller, unless forced off}
  225.             end    else
  226.             begin        {Valid movie dimensions - scale}
  227.             
  228.                 ContVis:=(CS=Visible);        {Is controller forced}
  229.                 if (width >= (right * 2)) and (height >= (bottom*2 + ord(ContVis or (CS=Badge))*ContHeight)) then 
  230.                     begin right:= right * 2; bottom:= bottom * 2; end    {Can zoom to X2}
  231.                     else
  232.                 if (width < right) or (height < (bottom + ord(ContVis or (CS=Badge))*ContHeight)) then        {Must shrink to size}
  233.                     begin
  234.                         if (right-width) > (bottom-height) then                {Keep aspect ratio}
  235.                         begin             {Shrink to fit x}
  236.                             bottom:= (longint (bottom) * width) div right;
  237.                             right:=width;
  238.                         end else
  239.                         begin              {Shrink to fit y}
  240.                             right:= (longint (right) * height) div bottom;
  241.                             bottom:=height;
  242.                         end;
  243.                     
  244.                     end;
  245.                 
  246.                 if CS=Auto then ContVis:=bottom+ContHeight <= height;    {Vis if auto and room}
  247.                 
  248.             end;
  249.  
  250.  
  251.  
  252.             {Set moviebox position}
  253.             if CX then OffsetRect(MovBox,(width - right) div 2, 0)    {Center X}
  254.             else
  255.             if not AL then OffsetRect(MovBox, width - right, 0);    {Right X}
  256.             
  257.             if CY then OffsetRect(MovBox, 0, (height - (bottom+ord(ContVis or (CS=Badge))*ContHeight)) div 2) {Center Y}
  258.             else
  259.             if not AT then OffsetRect(MovBox, 0, height - (bottom+ord(ContVis or (CS=Badge))*ContHeight));    {Bottom Y}
  260.         
  261.             
  262.         end;    {Auto sizing}
  263.         
  264.         
  265.         CompErr := MCSetVisible(MovContr, ContVis);
  266.         if CompErr <> noErr then SysBeep(30);
  267.             
  268.         ContBox.top := bottom;
  269.         ContBox.left:= left;
  270.         ContBox.right:= right;
  271.         ContBox.bottom:= bottom + ContHeight;        {The controller is always there, even if you can't see it.}
  272.         CompErr:= MCPositionController (MovContr, MovBox, ContBox, mcScaleMovieToFit+mcTopLeftMovie);
  273.  
  274.     end; {With}
  275. end;
  276.  
  277.  
  278.  
  279. function PrepMovie (var dat: MyDataT): OSErr;        {Get the loaded movie ready for use.}
  280. var                                                    {Pitty the person who gets all the CompErr<>noErr}
  281.     CompErr: ComponentResult;
  282.     tempRect:Rect;
  283.     err:OSErr;
  284. begin
  285.     with dat, dat.Options do begin
  286.         GetMovieBox (Mov,tempRect);
  287.         SetMovieTimeValue (Mov, StartPosition);        {Restore last playback position}
  288.         err:= PrerollMovie (Mov, StartPosition, PlayRate);
  289.         err:= LoadMovieIntoRam(Mov, 0, GetMovieDuration(Mov), loadBackwardTrackEdits + loadForwardTrackEdits + unkeepInRam);  {Speed up disk access}
  290.         if HighQ then SetMoviePlayHints(Mov, hintsHighQuality, hintsHighQuality);
  291.         
  292.         MovContr := NewMovieController(Mov, tempRect, mcTopLeftMovie + mcNotVisible + ord(CS=Badge)*mcWithBadge);            {Attach a controller to movie}
  293.         if MovContr = nil then begin PrepMovie:= GetMoviesError; Exit (PrepMovie); end;
  294.         
  295.         CompErr := MCDoAction(MovContr, mcActionSetFlags, mcFlagSuppressMovieFrame + ord4(UsePalette) * ord4(mcFlagsUseWindowPalette));
  296.         if CompErr <> noErr then SysBeep(30);        
  297.         CompErr := MCDoAction(MovContr, mcActionSetPlayEveryFrame, ord4(Slide));                    {Play all frames}
  298.         if CompErr <> noErr then SysBeep(30);
  299.         CompErr := MCDoAction(MovContr, mcActionSetLooping, ord4((LP=Linear) or (LP=Palidrome)));    {Looping conrtol}
  300.         if CompErr <> noErr then SysBeep(30);
  301.         CompErr := MCDoAction(MovContr, mcActionSetLoopIsPalindrome, ord4(LP=Palidrome));            {Palindrome Looping control}
  302.         if CompErr <> noErr then SysBeep(30);
  303.         CompErr := MCDoAction(MovContr, mcActionSetVolume, ord4(Vol));                                {Set volume}
  304.         if CompErr <> noErr then SysBeep(30);
  305.         CompErr := MCDoAction(MovContr, mcActionSetKeysEnabled, ord4(false));            {Disable control by keyboard}
  306.         if CompErr <> noErr then SysBeep(30);
  307.         CompErr := MCEnableEditing(MovContr, false);                                    {Disable editing}
  308.         if CompErr <> noErr then SysBeep(30);
  309.         CompErr := MCDoAction(MovContr, mcActionPlay, ord4(PlayRate));                    {Set play speed}
  310.         if CompErr <> noErr then SysBeep(30);
  311.         CompErr := MCDoAction(MovContr, mcActionActivate, nil);                            {Make sure activated}
  312.         if CompErr <> noErr then SysBeep(30);
  313.     end;
  314.     PrepMovie:=noErr;
  315. end;
  316.  
  317.  
  318.  
  319. procedure CloseIt (var dat: MyDataT);            {Close movie's data (but not the MyDataT itself) }
  320.  
  321. begin
  322.     if @dat = nil then Exit (CloseIt);
  323.     with dat do begin
  324.         if MovContr <> nil then DisposeMovieController(MovContr);
  325.         if Mov <> nil then DisposeMovie(Mov);
  326.                 
  327.         MovContr:= nil;
  328.         Mov:= nil;
  329.         Loaded:=false;
  330.     end;
  331. end;
  332.  
  333.  
  334.  
  335. { ------------------------------------------------------------------------------------
  336.     SetupDrawState:  Set up port, clipping, origin, color, stuff...
  337.     Set 'printing' to true to avoid non-print compatible stuff.
  338.     
  339.   ------------------------------------------------------------------------------------}
  340.   
  341.   
  342. function SetupDrawState (var dat:MyDataT):Boolean;
  343. var
  344.     oldForeColor, oldBackColor: RGBColor;
  345.     CompErr: ComponentResult;
  346. begin
  347.     if @dat = nil then begin SetupDrawState:=false; Exit (SetupDrawState); end;
  348.     
  349.     with dat do if (NWindP <> nil) & (MovContr <> nil) then
  350.     begin
  351.         with GraphicsState, NWindP^.window^ do begin
  352.             GetPort (SPort);                                    {Save and set port}
  353.             SetPort (GrafPtr(port));                            {Set my port}
  354.             SWMOrigin:= port^.portRect.topLeft;                    {Save the Window Manager's origin}
  355.             SetOrigin (portx, porty);                            {Set my origin}
  356.                 
  357.             if (not DidSave) or (SOrigin.v <>porty) or (SOrigin.h <> portx) or PortChanged then {Window stuff changed}
  358.             begin
  359.                 with NWindP^.clipRect do SetRectRgn (TempRegion, left+portx, top+porty, right+portx, bottom+porty);    {Movie's window region}     
  360.                 
  361.                 if PortChanged then                        {NPP_SetWindow sets this to true so it catches the change}
  362.                 begin
  363.                     SetClip (TempRegion);
  364.                     GetForeColor (oldForeColor);        {Save the current colors}
  365.                     GetBackColor (oldBackColor);
  366.                     ForeColor (blackColor);                {Normal, fast-draw, black&white}
  367.                     BackColor (whiteColor);
  368.                     CompErr:= MCSetControllerPort (MovContr, port);    {Set new port; it uses color settings}
  369.                     if CompErr <> noErr then SysBeep(30);
  370.                     SetTheMovieSize (dat);                {Reset the size of the movie to match the window}
  371.                     RGBForeColor (oldForeColor);        {Restore current colors}
  372.                     RGBBackColor (oldBackColor);
  373.                     InvalRgn (TempRegion);                {Netscape can do this wrong so do it again...}
  374.                     PortChanged:= false;                 {Reset value}
  375.                 end;
  376.                 
  377.                 CompErr:= MCSetClip (MovContr, TempRegion, TempRegion);
  378.                 
  379.                 SOrigin.h:=portx; SOrigin.v:= porty;    
  380.                 
  381.             end;    {Something changed}
  382.             
  383.             DidSave:= true;                {Reset flags and checks}
  384.         end;    {With}
  385.  
  386.         
  387.     end else GraphicsState.DidSave:= false;    {Variables ok}
  388.  
  389.     SetupDrawState:= dat.GraphicsState.DidSave;
  390. end;
  391.  
  392. procedure RestoreDrawState (var dat:MyDataT);
  393. begin
  394.     with dat.GraphicsState do if DidSave then
  395.     begin
  396.         SetOrigin (SWMOrigin.h, SWMOrigin.v);        {Restore Window Manager's origin and current port}
  397.         SetPort (SPort);
  398.     end;
  399. end;
  400.  
  401.  
  402. procedure ControlledUpdate (var dat:MyDataT; printing:boolean);        {Update the movie with the port set correctly}
  403. var
  404.     CompErr: ComponentResult;
  405. begin
  406.     with dat do
  407.         if SetupDrawState(dat) then
  408.         begin
  409.             CompErr:= MCDraw(MovContr, GrafPtr(NWindP^.window^.port));
  410.             RestoreDrawState (dat);
  411.         end;
  412. end;
  413.             
  414.  
  415. function ControlledMovieEvent (var dat:MyDataT; var event: EventRecord): integer;        {Handle events with the port set correctly}
  416. begin
  417.     if SetupDrawState(dat) then
  418.     begin
  419.         ControlledMovieEvent:= MCIsPlayerEvent(dat.MovContr, event);
  420.         RestoreDrawState (dat);
  421.     end else ControlledMovieEvent:=0;
  422. end;                    
  423.  
  424.  
  425. procedure CopyC2P (c: charstar; var p: Str255);            {Non-destructive C to P string converter}
  426. var                                                        {charstar is ^packed array [1..1] of char}
  427.     i:integer;
  428. begin
  429.     i:=1;
  430.     while (i<=255) & (ord(c^[i]) <>0) do begin
  431.         p[i]:= c^[i];
  432.         i:= succ (i);
  433.     end;
  434.     p[0]:= char(i-1);
  435. end;
  436.  
  437.  
  438.  
  439.  
  440.  
  441. {/------------------------------------------------------------------------------------
  442. // NPP_Initialize:
  443. //------------------------------------------------------------------------------------}
  444. function NPP_Initialize: NPError;
  445. var
  446.     result: longint;    {not used}
  447. begin
  448.     if Gestalt(gestaltQuickTime, result) = noErr then        {Must have QuickTime!!!! }
  449.     begin
  450.         if EnterMovies = noErr then NPP_Initialize:=NP_NOERR else NPP_Initialize:=NPERR_MODULE_LOAD_FAILED_ERROR;
  451.     end else
  452.         NPP_Initialize:=NPERR_MODULE_LOAD_FAILED_ERROR;
  453. end;
  454.  
  455.  
  456. {/------------------------------------------------------------------------------------
  457. // NPP_Shutdown:
  458. //------------------------------------------------------------------------------------}
  459. procedure NPP_Shutdown;
  460. var
  461.     result: longint;    {not used}
  462. begin
  463.     if Gestalt(gestaltQuickTime, result) = noErr then ExitMovies;        {Must have QuickTime!!!! }
  464. end;
  465.  
  466.  
  467. {/------------------------------------------------------------------------------------
  468. // NPP_New:
  469.     Create space for data storage
  470. //------------------------------------------------------------------------------------}
  471. function NPP_New (pluginType: NPMIMEType;
  472.                 var instance: NPP;
  473.                 mode: integer;
  474.                 argc: integer;
  475.                 argn: arglist;
  476.                 argv: arglist;
  477.                 recalled: NPSavedDataPtr):NPError;
  478.  
  479. var
  480.     i:integer;            {Counts through argc}
  481.     NewVol:longint;        {Need a longint for a VAR param}
  482.     V,N:Str255;            {Pascal strings for argn and argv}
  483.     s:Str255;
  484. begin
  485.     instance.pdata := NPN_MemAlloc(sizeof(MyDataT));        {Make my variable space}
  486.     if instance.pdata = nil then begin NPP_New:= NPERR_OUT_OF_MEMORY_ERROR; Exit (NPP_New); end;
  487.     
  488.     with MyDataP(instance.pdata)^ do begin        {Set everything to safe values}
  489.         NWindP := nil;
  490.         Loaded:=false;
  491.         Mov:= nil;
  492.         MovContr:= nil;
  493.         MovFileRef:= 0;
  494.         with TheFile do begin
  495.             vRefNum:=0;
  496.             parID:= 0;
  497.             name:= '';
  498.         end;
  499.         
  500.         with GraphicsState do begin
  501.             DidSave:= false;
  502.             PortChanged:= false;
  503.         end;
  504.         
  505.         TempRegion:= NewRgn;
  506.         if TempRegion = nil  then begin NPP_New:= NPERR_OUT_OF_MEMORY_ERROR; Exit (NPP_New); end;
  507.  
  508.         CopyC2P (pluginType, s);                        {Find out what kind of a file this is}
  509.         WhatIsIt (s, MacFileType, Options.MediaKind);
  510.         
  511.         {Set all options to default}
  512.         with Options do begin
  513.         
  514.             CX:=true; CY:=true; AL:= false; AT:= false;        {Center x and y}
  515.             F:=false;                                        {Auto size (not fixed)}
  516.             
  517.             case MediaKind of    {Control settings}
  518.                 'V': CS:=Auto;                                {Video - Auto control}
  519.                 'S': CS:=None;                                {Still image - no control}
  520.                 'A': CS:=Visible;                            {Audio - control}
  521.             end;
  522.             
  523.             StartPosition:=0;                                {Start at begining by default}
  524.             PlayRate:=0;                                    {Don't start auto-playing}
  525.             LP:= Once;                                        {No looping}
  526.             Vol:= 0256;                                        {Volume = 1 (16 bit fixed) }
  527.             Slide:=false;                                    {Slideshow mode off}
  528.             
  529.             case MediaKind of    {HiQ settings}
  530.                 'V': HighQ:= false;                            {Video - High quality (slow) off}
  531.                 'S': HighQ:= true;                            {Still image - High quality on}
  532.                 'A': HighQ:= false;                            {Audio - High quality off}
  533.             end;
  534.             
  535.             UsePalette:=false;                                {Don't use custom palette}
  536.             
  537.             {Override defaults with HTML options}
  538.             for i := 1 to argc do
  539.             begin
  540.                 CopyC2P (argv^[i], V);                {Git them C strings outa here!}
  541.                 UpperString(V, true);                {Case insensitve}
  542.                 CopyC2P (argn^[i], N);
  543.                 UpperString(N, true);
  544.                 
  545.                 if N = 'PLACE' then
  546.                 begin
  547.                     if Pos('T', V) > 0 then begin CY:=false; AT:=true; end;        {Top}
  548.                     if Pos('B', V) > 0 then begin CY:=false; AT:=false; end;    {Bottom}
  549.                     if Pos('L', V) > 0 then begin CX:=false; AL:=true; end;        {Left}
  550.                     if Pos('R', V) > 0 then begin CX:=false; AL:=false; end;    {Right}
  551.                     if Pos('F', V) > 0 then F:=true;                            {Force fit}
  552.                 end;
  553.                 
  554.                 if N = 'CONTROL' then
  555.                 begin
  556.                     if Pos('H', V) > 0 then CS:= Hidden;        {Hidden controller}
  557.                     if Pos('V', V) > 0 then CS:= Visible;        {Visible controller}
  558.                     if Pos('0', V) > 0 then CS:= None;            {No movie contallability}
  559.                     if Pos('B', V) > 0 then CS:= Badge;            {No controller, but put up the badge icon}
  560.                 end;
  561.                 
  562.                 if N = 'PLAY' then                                        {PLAY=<integer percent>}
  563.                 begin
  564.                     StringToNum(V, PlayRate);
  565.                     PlayRate := (PlayRate * 065536) div longint(0100);  {Convert percent to fixed}
  566.                 end;
  567.                 
  568.                 
  569.                 if N = 'LOOP' then
  570.                 begin
  571.                     if Pos('L', V) > 0 then LP:= Linear;
  572.                     if Pos('P', V) > 0 then LP:= Palidrome;
  573.                 end;
  574.                 
  575.                 if N = 'VOL' then                                        {VOL=<integer percent>}
  576.                 begin
  577.                     StringToNum(V, NewVol);
  578.                     Vol := (NewVol * longint(0256)) div longint(0100);  {Convert percent to fixed}
  579.                 end;
  580.                 
  581.                 if N = 'HINTS' then
  582.                 begin
  583.                     if Pos('S', V) > 0 then Slide:=true;                    {Slideshow mode - all frames at High Q}
  584.                     if Pos('Q', V) > 0 then HighQ:=true;                    {High Q mode}
  585.                     if Pos('P', V) > 0 then UsePalette:=true;                {Use custom palette}
  586.                 end;
  587.             end;    {argc loop}
  588.             
  589.             
  590.             if recalled <> nil then                {If there are saved states then get them as an override}
  591.             with SavedDataPtrT(@recalled^.buf)^ do
  592.             begin
  593.                 StartPosition:= LastTime;        {These will be used at PrepMovie}
  594.                 PlayRate:= LastRate;
  595.                 Vol:= LastVol;
  596.             end;
  597.             
  598.             
  599.         end;    {with Options}
  600.     end;    {with MyDataP(instance.pdata)^}
  601.     
  602.     NPP_New:= NPERR_NO_ERROR;
  603. end;
  604.  
  605.  
  606.  
  607.  
  608. {/------------------------------------------------------------------------------------
  609. // NPP_Destroy:
  610. //------------------------------------------------------------------------------------}
  611. function NPP_Destroy (var instance:NPP; var save: NPSavedDataPtr):NPError;
  612.  
  613. var
  614.     unused:TimeRecord;
  615.     s:SavedDataPtrT;
  616.     TotalSize:integer;
  617. begin
  618.                                                  
  619.     with MyDataP(instance.pdata)^ do
  620.     begin
  621.         if TempRegion <> nil then begin DisposeRgn (TempRegion); TempRegion:= nil; end;
  622.         if MovContr <> nil then
  623.         begin
  624.             TotalSize:=sizeof(NPSavedData)+sizeof(SavedDataT);    {The size of Netscape's record plus mine at the end}
  625.             save:= NPSavedDataPtr (NPN_MemAlloc(TotalSize));    {Get memory for storage}
  626.             if save <> nil then
  627.             begin
  628.                 s:=SavedDataPtrT(@save^.buf);                    {Put data at the position of the buf marker}
  629.                 s^.LastTime:= GetMovieTime (Mov, unused);        {Save the current movie time for next time}
  630.                 if MCDoAction(MovContr, mcActionGetPlayRate, @s^.LastRate) <> noErr then        {Save play speed}
  631.                     s^.LastRate:=0;
  632.                 if MCDoAction(MovContr, mcActionGetVolume, @s^.LastVol) <> noErr then            {Save volume control}
  633.                     s^.LastVol:=0;
  634.                 save^.len := TotalSize;
  635.  
  636.             end;    {save <>nil}
  637.         end;    {MovContr<> nil}
  638.     end;
  639.     
  640.     CloseIt (MyDataP(instance.pdata)^);
  641.             
  642.     NPN_MemFree(instance.pdata);
  643.     instance.pdata := nil;    
  644.     NPP_Destroy:= NPERR_NO_ERROR;
  645. end;
  646.  
  647.  
  648.  
  649. {/------------------------------------------------------------------------------------
  650. // NPP_SetWindow:
  651. //------------------------------------------------------------------------------------}
  652. function NPP_SetWindow (var instance: NPP; NwindowP: NPWindowPtr): NPError;
  653. begin
  654.     with MyDataP(instance.pdata)^ do begin
  655.         NWindP := NwindowP;                {Save a pointer to Netscape's dynamic window structure}
  656.         check1:= NWindP^.window;        {Redundancy to later check for corruption}
  657.         check2:= NWindP^.window^.port;
  658.         GraphicsState.PortChanged:= true;    {Let SetupDrawState know that it needs to reset the graphics stuff}
  659.     end;
  660.                 
  661.     NPP_SetWindow:= NPERR_NO_ERROR;
  662. end;
  663.  
  664.  
  665.  
  666. {/------------------------------------------------------------------------------------
  667. // NPP_NewStream:
  668. //------------------------------------------------------------------------------------}
  669. function NPP_NewStream        (var instance: NPP;
  670.                             Mtype: NPMIMEType;
  671.                             var stream: NPStream;
  672.                             seekable: boolean;
  673.                             var stype: integer):NPError;
  674. begin
  675.     MyDataP(instance.pdata)^.Loaded:= false;        {We╒re loading now}
  676.     
  677.     stype:=NP_ASFILE;                            {Tell Netscape that I need a file.}
  678.     NPP_NewStream:= NPERR_NO_ERROR;
  679. end;
  680.  
  681.  
  682.  
  683. { ------------------------------------------------------------------------------------
  684.     NPP_WriteReady:
  685.   ------------------------------------------------------------------------------------}
  686. function NPP_WriteReady (var instance: NPP; var stream: NPStream): longint;
  687.  
  688. begin
  689.     NPP_WriteReady:= $0FFFFFFF;        {Number of bytes ready to accept in NPP_Write() }
  690. end;                                {Not like it matters, I don't do memory streams}
  691.  
  692.  
  693.  
  694. { ------------------------------------------------------------------------------------
  695.     NPP_Write:
  696.   ------------------------------------------------------------------------------------}
  697. function NPP_Write (var instance: NPP; var stream: NPStream; offset:longint; len: longint; buffer: Ptr): longint;
  698. begin
  699.     NPP_Write:= 0;                    {I don't do memory streams.}
  700. end;
  701.  
  702.  
  703.  
  704. { ------------------------------------------------------------------------------------
  705.     NPP_DestroyStream  - Done loading
  706.   ------------------------------------------------------------------------------------}
  707. function NPP_DestroyStream (var instance: NPP; var stream: NPStream; reason: NPError) :NPError;
  708. begin
  709.     if reason = NP_NOERR then with MyDataP(instance.pdata)^ do begin    {Loading complete}
  710.     
  711.         if OpenFromFile (MyDataP(instance.pdata)^) = noErr then    {Open the movie file}
  712.             begin
  713.                 Loaded := true;                            {OK}
  714.                 NPP_DestroyStream:= NPERR_NO_ERROR;    
  715.             end else begin                                {File didn't open}
  716.                 CloseIt (MyDataP(instance.pdata)^);
  717.                 NPP_DestroyStream:= NPERR_MODULE_LOAD_FAILED_ERROR;
  718.             end;
  719.     
  720.     
  721.         if Loaded & (noErr = PrepMovie (MyDataP(instance.pdata)^)) then    {Get movie ready for playing}
  722.         begin;
  723.             NPP_DestroyStream:= NPERR_NO_ERROR;            {OK}    
  724.         end else
  725.         begin
  726.             CloseIt (MyDataP(instance.pdata)^);            {Movie didn't prep}
  727.             NPP_DestroyStream:= NPERR_MODULE_LOAD_FAILED_ERROR;
  728.         end;
  729.         
  730.     end else begin    {Loading incomplete}
  731.         CloseIt (MyDataP(instance.pdata)^);
  732.         NPP_DestroyStream:= NPERR_MODULE_LOAD_FAILED_ERROR;
  733.     end;
  734.     
  735. end;
  736.  
  737.  
  738. { ------------------------------------------------------------------------------------
  739.     NPP_StreamAsFile:
  740.   ------------------------------------------------------------------------------------}
  741. procedure NPP_StreamAsFile (var instance: NPP; var stream: NPStream; fname: charstar);
  742. var
  743.     name:Str255;            {I hope the path isn't too long! }
  744. begin
  745.     CopyC2P (fname,name);    {Set up info for loading from a file}
  746.     
  747.     with MyDataP(instance.pdata)^ do begin
  748.         if FSMakeFSSpec (0,0, name, TheFile) <> noErr then SysBeep (30);
  749.     end;
  750.         
  751. end;
  752.  
  753.  
  754.  
  755. { ------------------------------------------------------------------------------------
  756.     NPP_Print:
  757.   ------------------------------------------------------------------------------------}
  758. procedure NPP_Print (var instance: NPP; var PrintInfo: NPPrint);
  759. var
  760.     pic: PicHandle;
  761.     now: TimeValue;
  762.     unused: TimeScale;
  763.     bounds:Rect;
  764. begin
  765.     with MyDataP(instance.pdata)^ do begin
  766.         if PrintInfo.mode = NP_FULL then begin
  767.                 {
  768.                     If we╒re fullscreen, we don╒t want to take over printing,
  769.                     so return false.  NPP_Print will be called again with
  770.                     mode = NP_EMBED.
  771.                 }
  772.                 PrintInfo.fullPrint.pluginPrinted := false;
  773.             end
  774.             else        {If not fullscreen, we must be embedded}
  775.                 begin
  776.                     with PrintInfo.embedPrint.window.window^ do
  777.                     begin
  778.                         SetOrigin (portx, porty);
  779.                         with NWindP^.clipRect do SetRectRgn (TempRegion, left+portx, top+porty, right+portx, bottom+porty);         
  780.                         {SetClip (TempRegion);}
  781.                         now:= MCGetCurrentTime (MovContr, unused);
  782.                         GetMovieBox (Mov, bounds);
  783.                         pic:= GetMoviePict (Mov, now);
  784.                         if pic <> nil then begin
  785.                             DrawPicture (pic, bounds);
  786.                             KillPicture (pic);
  787.                         end;
  788.                     end;
  789.                 end;
  790.     end;
  791. end;
  792.  
  793.  
  794.  
  795.  
  796. { ------------------------------------------------------------------------------------
  797.     NPP_HandleEvent:
  798.     Mac-only.
  799.   ------------------------------------------------------------------------------------}
  800. function NPP_HandleEvent (var instance: NPP; var event: EventRecord): integer;
  801. var
  802.     CompErr:ComponentResult;
  803.     Took:boolean;
  804. begin
  805.     Took:=false;
  806.     
  807.     if (@instance=nil) | (instance.pdata = nil) then begin NPP_HandleEvent:=0;Exit (NPP_HandleEvent); end;
  808.     
  809.         
  810.     with MyDataP(instance.pdata)^ do if Loaded then begin
  811.         
  812.         if not Corruption (MyDataP(instance.pdata)^) then    {Make sure Netscape isn't confused about the window}
  813.         begin    
  814.             if event.what = getFocusEvent then            {Activate controller}
  815.             begin
  816.                 CompErr := MCDoAction(MovContr, mcActionActivate, nil);
  817.                 Took:=true;
  818.             end;
  819.     
  820.             {if event.what = loseFocusEvent then}        {Deactivate controller, not handled because it requires an extra}
  821.             {begin}                                        {mouse click to reactivate. }
  822.             {end;}
  823.             
  824.             if event.what = updateEvt then
  825.                 begin
  826.                     {event.message:= ord(NWindP^.window^.port);}            {Netscape doesn't make REAL event records.}
  827.                     ControlledUpdate (MyDataP(instance.pdata)^ ,false);        {Don't let MCIsPlayerEvent call BeginUpdate}
  828.                     Took:=true;
  829.                 end;
  830.                 
  831.             if (event.what = mouseDown) and (Options.CS = None) then Took:=true;    {Mask mouse-down if Mouse control is off}
  832.             
  833.             {if event.what = adjustCursorEven then ;}                {No fancy cursor handling}
  834.             
  835.             if (not Took) and (event.what < adjustCursorEven) then Took:= ControlledMovieEvent(MyDataP(instance.pdata)^, event) = 1; {Handle MacOS events}
  836.         end;    {Integrity checked OK}
  837.         
  838.     end;    {With}
  839.     
  840.      NPP_HandleEvent:=ord(Took);
  841. end;
  842.  
  843.  
  844. {And they viewed multimedia hapily ever after.}
  845. {The    }        
  846. end.
  847.